import u from 'underscore';
import fs from 'fs';
import path from 'path';
import log4js from 'log4js';

const PROJECT_NAME = 'react.starkit';

/**
 * 日志输出分类定义
 *
 * @const {Array}
 */
const CATEGORIES = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];


/**
 * 递归创建目录
 *
 * @param {string} dirpath 需要创建的目录path
 * @param {string=} dirname 需要创建的目录名
 */
function mkdir(dirpath, dirname) {
    if (fs.existsSync(dirpath)) {
        return;
    }

    if (!dirname) {
        mkdir(dirpath, path.dirname(dirpath));
    }
    else if (dirname !== path.dirname(dirpath)) {
        mkdir(dirpath);
    }
    else if (fs.existsSync(dirname)) {
        fs.mkdirSync(dirpath);
    }
    else {
        mkdir(dirname, path.dirname(dirname));
        fs.mkdirSync(dirpath);
    }
}


function getLogFileName(path, category) {
    path = path + category.toString() + '/';

    // https://github.com/nomiddlename/log4js-node/issues/121
    mkdir(path);

    let filename = `${PROJECT_NAME}.${category}.log`;

    return path + filename;
}


function getAppenders(level = 'fatal') {
    // 包括level本身
    let end = u.indexOf(CATEGORIES, level) + 1;

    return CATEGORIES.slice(0, end);
}


function getConfiguration(dirname) {
    let appenders = {};
    let categories = {};

    const MAX_LEVEL = 'fatal';

    u.each(CATEGORIES, category => {
        let filename = getLogFileName(dirname, category);
        let multiFileAppender = `${category}_logfile`;

        appenders[multiFileAppender] = {
            type: 'dateFile',
            filename,
            compress: false,
            pattern: '.yyyyMMdd',
            maxLogSize: 10485760, // 10M
            backups: 20, // default 5 当文件内容超过文件存储空间时，自增长备份文件数量限制
            layout: {
                type: 'pattern',
                pattern: '[%z] [%d] %[[%c]%] - %m'
            }
        };

        appenders[category] = {
            type: 'logLevelFilter',
            appender: multiFileAppender,
            level: 'all',
            maxLevel: MAX_LEVEL
        };

        categories[category] = {
            appenders: ['console', ...getAppenders(category, MAX_LEVEL)],
            level: category
        };

    });

    return {
        appenders,
        categories
    };
}

function initAllLogger(dirname, scope) {

    const {appenders, categories} = getConfiguration(dirname);

    // log4js Version 2.x
    log4js.configure({
        appenders: {
            console: {
                type: 'console',
                layout: {
                    type: 'pattern',
                    pattern: '[%z] [%d] %[[%c]%] - %m'
                }
            },
            ...appenders
        },
        categories: {
            'default': {
                appenders: ['console'],
                level: 'info'
            },
            ...categories
        }
    });

    scope.logger = {};

    u.each(CATEGORIES, category => {
        let logger = log4js.getLogger(category);

        // 给 global.logger 不同级别日志绑上不同的输出源
        // 例：global.logger.info = logger.info
        if (logger[category]) {
            scope.logger[category] = u.bind(logger[category], logger);
        }
    });
}

initAllLogger(path.join(__dirname, '../../../logs/'), global);
